package id.zelory.compressor.sample;

import id.zelory.compressor.Compressor;
import id.zelory.compressor.Util;
import id.zelory.compressor.constraint.CompressFormat;
import id.zelory.compressor.constraint.Compression;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.Image.ScaleMode;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.AlphaType;
import ohos.media.image.common.ColorSpace;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import static java.lang.Math.log10;

public class MainAbility extends Ability {
    long time;
    List<File> picFiles = new ArrayList<>();
    File imageFile = null;
    int index;
    EventRunner eventRunner = EventRunner.create(true);
    EventHandler eventHandler = new CompressHandler(eventRunner);

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_Ability_main);
        setBackgroundColor();
        setupClickListener();
        picFiles.add(Util.resPathToFile(getContext(), "resources/rawfile/pic2.png"));
        picFiles.add(Util.resPathToFile(getContext(), "resources/rawfile/pic7.jpg"));
    }

    private void setupClickListener() {
        Button chooseImageButton = (Button) findComponentById(ResourceTable.Id_chooseImageButton);
        if (chooseImageButton != null) {
            chooseImageButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    new ToastDialog(MainAbility.this).setText("chooseImge").show();
                    chooseImage();
                }
            });
        }
        Button compressImageButton = (Button) findComponentById(ResourceTable.Id_compressImageButton);
        if (compressImageButton != null) {
            compressImageButton.setClickedListener(component -> {
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        File result = compressImage(imageFile);
                        InnerEvent event = InnerEvent.get(1, 0, result);
                        eventHandler.sendEvent(event, 0, EventHandler.Priority.IMMEDIATE);
                    }
                };
                eventHandler.postTask(task);

                ToastDialog toast = new ToastDialog(getContext());
                toast.setContentText("Start compress!");
                toast.show();
            });
        }
        Button customCompressImageButton = (Button) findComponentById(ResourceTable.Id_customCompressImageButton);
        if (customCompressImageButton != null) {
            customCompressImageButton.setClickedListener(component -> {
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        File result = customCompressImage(imageFile);
                        InnerEvent event = InnerEvent.get(1, 0, result);
                        eventHandler.sendEvent(event);
                    }
                };
                eventHandler.postTask(task);
                ToastDialog toast = new ToastDialog(getContext());
                toast.setContentText("Start custom compress!");
                toast.show();
            });
        }
    }

    private void test() {
        ImageSource imageSource = ImageSource.create(Util.resPathToFile(getContext(), "resources/rawfile/pic2.png"), null);
        PixelMap bmp = imageSource.createPixelmap(null);
        Size size = bmp.getImageInfo().size;
    }

    private void chooseImage() {
        clearImage();
        index = index + 1;
        if (index == picFiles.size()) {
            index = 0;
        }
        imageFile = picFiles.get(index);
        Image image = (Image) findComponentById(ResourceTable.Id_actualImageView);
        PixelMap pixelMap = Util.loadBitmap(imageFile);
        printLog("origin", pixelMap);
        image.setPixelMap(pixelMap);
        Text actualSize = (Text) findComponentById(ResourceTable.Id_actualSizeTextView);
        actualSize.setText("Size : " + getReadableFileSize(imageFile.length()));

    }

    private void printLog(String tag, PixelMap pixelMap) {
        ImageInfo imageInfo = pixelMap.getImageInfo();
        Size size = imageInfo.size;
        AlphaType alphaType = imageInfo.alphaType;
        ColorSpace colorSpace = imageInfo.colorSpace;
        PixelFormat format = imageInfo.pixelFormat;
    }


    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);
    }

    private File compressImage(File file) {
        this.time = new Date().getTime();
        Compressor compressor = new Compressor();
        return compressor.compress(getContext(), file, null);
    }

    private File customCompressImage(File file) {
        this.time = new Date().getTime();
        ImageSource imageSource = ImageSource.create(file, null);
        Size size = imageSource.getImageInfo().size;
        Compressor compressor = new Compressor();
        Compression compression = new Compression();
        compression.resolution(size.width, size.height);
        compression.quality(90);
        compression.format(CompressFormat.JPEG);
        compression.size(1024 * 1024, 0, 0);
        return compressor.compress(getContext(), file, compression);
    }

    private void setCompressedImage(File compressedImage) {
        this.time = new Date().getTime() - this.time;
        this.time = 0;
        try {
            Image image = (Image) findComponentById(ResourceTable.Id_compressedImageView);
            ImageSource imageSource = ImageSource.create(imageFile.getCanonicalFile(), null);
            PixelMap bitmap = imageSource.createPixelmap(null);
            printLog("compress", bitmap);
            image.setPixelMap(bitmap);
            Text compressedSize = (Text) findComponentById(ResourceTable.Id_compressedSizeTextView);
            compressedSize.setText("Size : " + getReadableFileSize(compressedImage.length()));
            Text toastText = (Text) findComponentById(ResourceTable.Id_toastTextView);
            toastText.setText("Compressed image save in " + compressedImage.getPath());
        } catch (IOException ex) {
            Logger.getLogger(MainAbility.class.getName()).log(Level.SEVERE,ex.getMessage());
        }
    }

    private void clearImage() {
        Image actualImage = (Image) findComponentById(ResourceTable.Id_compressedImageView);
        actualImage.setPixelMap(null);
        Image compressedImage = (Image) findComponentById(ResourceTable.Id_compressedImageView);
        compressedImage.setPixelMap(null);
        Text actualSizeText = (Text) findComponentById(ResourceTable.Id_actualSizeTextView);
        actualSizeText.setText("Size : -");
        Text compressedSizeText = (Text) findComponentById(ResourceTable.Id_compressedSizeTextView);
        compressedSizeText.setText("Size : -");
    }

    private void setBackgroundColor() {
        Image actualImage = (Image) findComponentById(ResourceTable.Id_actualImageView);
        actualImage.setScaleMode(ScaleMode.INSIDE);
        ShapeElement actualBackground = new ShapeElement();
        actualBackground.setRgbColor(getRandomColor());
        actualImage.setBackground(actualBackground);
        Image compressedImage = (Image) findComponentById(ResourceTable.Id_compressedImageView);
        compressedImage.setScaleMode(ScaleMode.INSIDE);
        ShapeElement compressedBackground = new ShapeElement();
        compressedBackground.setRgbColor(getRandomColor());
        compressedImage.setBackground(compressedBackground);
    }

    private RgbColor getRandomColor() {
        SecureRandom random = new SecureRandom();
        return new RgbColor(random.nextInt(256), random.nextInt(256), random.nextInt(256), 100);
    }

    private String getReadableFileSize(Long size) {
        if (size <= 0) {
            return "0";
        }
        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (log10(size.doubleValue()) / log10(1024.0));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024.0, digitGroups)) + " " + units[digitGroups];
    }

    class CompressHandler extends EventHandler {

        public CompressHandler(EventRunner runner) throws IllegalArgumentException {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            switch (event.eventId) {
                case 1:
                    File imgFile = (File) event.object;
                    getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
                        @Override
                        public void run() {
                            setCompressedImage(imgFile);
                        }
                    });
                    break;
            }
        }
    }
}


